//
//Copyright 2009 Google Inc.
//
//Licensed under the Apache License, Version 2.0 (the "License");
//you may not use this file except in compliance with the License.
//You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
//Unless required by applicable law or agreed to in writing, software
//distributed under the License is distributed on an "AS IS" BASIS,
//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//See the License for the specific language governing permissions and
//limitations under the License.
//

/**
 * @fileoverview This is an HTML nav bar widget that allows users to navigate
 * through the content on digital content wizard website.
 */

/**
 * Creates a new Navigation Bar widget. This widget creates a navigation UI,
 * which allows users to navigate through the content items on the digital
 * content wizard site. It is required that the HTML should have a div present
 * with the id menuDivId, which is passed as an argument to this constructor.
 * @param {string} menuDivId Identifier of the menu div.
 * @param {number} noOfLevels Number of navigation leves 2/3.
 * @constructor
 */
digitalContentWizard.NavigationBar = function(menuDivId, noOfLevels) {
  /**
   * Dom id of the navigation sidebar div element.
   * @type {string}
   */
  this.menuDivId = menuDivId;
  /**
   * Number of levels of the navigation sidebar.
   * @type {number}
   * @private
   */
  this.levels_ = noOfLevels;
  /**
   * Navigation sidebar element.
   * @type {HTMLElement}
   */
  this.navElement = document.getElementById(this.menuDivId);
};

/**
 * Initializes the state of the sidebar. It defines the onClick method for
 * sidebar. This function basically performs appropriate changes in the
 * sidebar to open and close appropriate elements when a click happens.
 */
digitalContentWizard.NavigationBar.prototype.initState = function() {
  window.$('#menu ul').hide();
  window.$("ul[level = 'level2']").slideUp('normal');
  window.$("ul[level = 'level3']").slideUp('normal');
  window.$("ul[level = 'level1']").slideDown('normal');
  window.$('#menu li a').click(
    /**
     * Adjusts sidebar as a response to the click on any one of the sidebar
     * links. Sidebar has levels_ no of levels. When a click is performed on a
     * link at level i, all the other open elements at level i are closed and
     * the element, which is clicked in opened, so that all the links at level
     * i+1 for the clicked element are displayed.
     * @return {boolean} False when an element having further links down the
     * tree is clicked.
     */
    function() {
      var checkElement = window.$(this).next();
      var levelAttr = checkElement.attr('level');
      if ((checkElement.is('ul')) && (checkElement.is(':visible'))) {
        if (levelAttr != 'level1') {
          return false;
        }
      }
      if ((checkElement.is('ul')) && (!checkElement.is(':visible'))) {
        if (levelAttr == 'level2') {
          window.$("ul[level = 'level2']").slideUp('normal');
          window.$("ul[level = 'level3']").slideUp('normal');
          checkElement.slideDown('normal');
          return false;
        }
        if (levelAttr == 'level3') {
          window.$("ul[level = 'level3']").slideUp('normal');
          checkElement.slideDown('normal');
          return false;
        }
      }
      return true;
    }  //End of function
  );
};

/**
 * Adjusts the navigation bar by opening appropriate level1 and level2 elements
 * of the nav bar.
 *
 * @param {string} val1 Value of level1 elements.
 * @param {string} val2 Value of level2 elements.
 */
digitalContentWizard.NavigationBar.prototype.adjust = function(val1, val2) {
  // Find out the required level1 element.
  var condition1 = "a[title = '" + val1 + "']";
  var condition2 = "a[title = '" + val2 + "']";
  // Slide down the level1 element in the navigation bar.
  window.$(condition1).next().slideDown('normal');
  // Get a reference to all li elements in the conditions container.
  var liNodes = window.$(condition1).next().children();
  // Get a reference to the required level2 ul element, which is the descendent
  // of one of li elements found above. The structure is <li> <a> </a> <ul>. We
  // reach at the required ul node.
  var level2Node = liNodes.children(condition2).next();
  // Slide down the level2 ul element found.
  level2Node.slideDown('normal');
};

/**
 * Creates navigation html elements for the specified json node.
 *
 * @param {string} jsonNode Json Node for the element to be rendered.
 * @param {Element} parentUlNode ul element. Current element to be rendered
 *                               should be the child of this ul node.
 * @param {number} level Current level of the element in the navigation
 *                       hierarchy.
 * @return {Element} li element with the data for the current json node.
 */
digitalContentWizard.NavigationBar.prototype.createNavTree = function(
jsonNode, parentUlNode, level)
{
  var liNode = document.createElement('li');
  var aNode = document.createElement('a');
  var ulNode = null;
  // Configure nodes.
  aNode.innerHTML = jsonNode.name;
  aNode.title = jsonNode.name;
  aNode.href = jsonNode.url;
  liNode.appendChild(aNode);
  if (level < this.levels_) {
    if (level != 0) {
      aNode.href = 'javascript:void(0);';
      parentUlNode.appendChild(liNode);
    }
    ulNode = document.createElement('ul');
    var nextLevel = level + 1;
    ulNode.setAttribute('level', 'level' + nextLevel);
    liNode.appendChild(ulNode);
    for (var childNode, i = 0; childNode = jsonNode.childNodes[i]; i++) {
      this.createNavTree(childNode, ulNode, level + 1);
    }
  } else {
    parentUlNode.appendChild(liNode);
  }
  return liNode;
};

/**
 * Renders HTML elements of navigation bar for the specified json object.
 *
 * @param {string} jsonObj Json object containing the hierarchical metadata
 *                         required to render the navigation bar.
 */
digitalContentWizard.NavigationBar.prototype.renderNavigationBar = function(jsonObj) {
  var liNode = this.createNavTree(jsonObj[0], null, 0);
  this.navElement.appendChild(liNode);
};

/**
 * Initializes the sidebar for the specified json objects. It includes
 * rendering the navigation bar and initializing its state.
 *
 * @param {string} jsonObj Json object containing the hierarchical metadata
 *                         required to render the navigation bar.
 */
digitalContentWizard.NavigationBar.prototype.initialize = function(jsonObj) {
  this.renderNavigationBar(jsonObj);
  this.initState();
};
